#include "SRSCoverTree.h"
#include "RandGen.h"
#include "Rawdata.h"
#include "ProjData.h"

#include <iostream>
using namespace std;


struct iwk_vector {
  float * I;
  float * W;
  float * K;
};


iwk_vector NA_plus4(float*arr_data, float*arr_f, int n, int d){
    float * I = (float*)malloc(sizeof(float)*n);
    float * W = (float*)malloc(sizeof(float)*n);
    float * K = (float*)malloc(sizeof(float)*n);


    float f_max = -99999999;
    int r = 0;
    for(int i=0;i<n;i++){
        if(arr_f[i]>f_max){
            f_max = arr_f[i];
            r = i;
        }
    }
    I[r] = r;
    W[r] = 0;
    K[r] = n;
    cout<<"f_max:"<<f_max<<endl;

    Proj_data* data_proj = new Proj_data(n, d, arr_data);
    SRS_Cover_Tree tree = SRS_Cover_Tree(n, d, data_proj);
    tree.tree_stat();

    float fi, fj;
    int cnt_k = 0, j=0, _dist = 0;

    for(int i=0;i<n;i++){
        if(i==r)continue;

        float * query = arr_data+d*i;
        tree.init_search(query);

        fi = arr_f[i];
        fj = fi;
        while(fj<=fi){
            res_pair res = tree.increm_knn_search_compressed();
//            cout<<"id:"<<res.id<<":"<<res.dist<<endl;
            fj =arr_f[res.id];
            cnt_k += 1;
            j = res.id;
            _dist = res.dist;
        }
        I[i] = j;
        W[i] = _dist;
        K[i] = cnt_k;
    }

    iwk_vector iwk = {I, W, K};
//    iwk.I = I;
//    iwk.W = W;
//    iwk.K = K;

//    cout<<"finish_search"<<endl;
//    tree.finish_search();
//    cout<<"free pointer"<<endl;
    return iwk;
}

#include <ctime>
#include <iostream>
#include <fstream>
using namespace std;

float * rand_data(long long n, int d){
    float * data = (float*)malloc(sizeof(float)*d*n);
    for(int i=0;i<d*n;i++)
        data[i] = (float)(i*i+i);
    return data;
}


int main(){
    const long long n = 5000;
    const int d = 2;
    float * data = rand_data(n, d);

    srand((int)time(0));  // 产生随机种子  把0换成NULL也行
    float * f = (float*)malloc(sizeof(float)*n);
    for(int i=0;i<n;i++){
//            f[i] = rand()%100;
        f[i] = i;
//        cout<<"i:"<<f[i]<<endl;
    }

    //Read Data
    //*************************************************
//    Raw_data<float> data_raw = Raw_data<float>(n, d, (char *)"G:/Music/ProCPlus/ProSR/data/data.txt");
//    data = data_raw.data;

    ifstream file_data("G:/Music/ProCPlus/ProSR/data/data.txt");
    for(int i=0;i<n*d;i++)file_data>>data[i];

    printf("read ok!\n");
//    for(int i=0;i<99;i++)
//        cout<<data[i*2]<<","<<data[i*2+1]<<endl;

    //Cover Tree Forward
    //*************************************************
    clock_t t1, t2;
    t1 = clock();
    iwk_vector iwk = NA_plus4(data, f, n, d);
    t2 = clock();
    cout<<"\nTime(s):"<<(double)(t2-t1)/CLOCKS_PER_SEC<<endl;
//    cout<<"sizepf iwk.I:"<<sizeof(iwk.I)<<":"<<iwk.I[0]<<endl;
//    cout<<"sizepf iwk.W:"<<sizeof(iwk.W)<<":"<<iwk.W[0]<<endl;
//    cout<<"sizepf iwk.K:"<<sizeof(iwk.K)<<":"<<iwk.K[0]<<endl;

    //Evaluate Accuracy
    //*************************************************
    float * anno = rand_data(n, 1);
    ifstream file_anno("G:/Music/ProCPlus/ProSR/data/anno.txt");


    float acc=0;
    for(int i=0;i<n;i++){
        file_anno>>anno[i];
        if(anno[i]==iwk.I[i])
            acc += 1.0;
        if(i<9)
            cout<<anno[i]<<endl;
    }
    acc = acc/n;
    cout<<"\nAccuracy:"<<acc<<endl;


    cout<<"Cover Tree finished!!!"<<endl;
    return 0;
}